

/* Includes ------------------------------------------------------------------*/
#include "vs1053.h"


/* Private variables ---------------------------------------------------------*/
/* 0 , henh.1 , hfreq.2 , lenh.3 , lfreq 5  */
uint8_t vs1053ram[5] = { 0 , 0 , 0 , 0 , 250 };
/*******************************************************************************
* Function Name  : delay_ms
* Description    : delay time
* Input          : - ms: time
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
static void delay_ms(uint32_t ms)
{
    uint32_t len;
    for (;ms > 0; ms --)
        for (len = 0; len < 100; len++ );
}
		
static void vs1053_SPI_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;

  RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE);
  /* SPI2 configuration */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);

  /* Enable SPI2  */
  SPI_Cmd(SPI2, ENABLE);
}


static void vs1053_SPI_SetSpeed( uint8_t SpeedSet)
{
  SPI_InitTypeDef SPI_InitStructure ;
    
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex ;
  SPI_InitStructure.SPI_Mode=SPI_Mode_Master ;
  SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b ;
  SPI_InitStructure.SPI_CPOL=SPI_CPOL_High ;
  SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge ;
  SPI_InitStructure.SPI_NSS=SPI_NSS_Soft ;

  if( SpeedSet == SPI_SPEED_LOW )
  {
      SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;
  }
  else 
  {
      SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_8;
  }
  SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB ;
  SPI_InitStructure.SPI_CRCPolynomial=7 ;
  SPI_Init(SPI2,&SPI_InitStructure);
}


uint8_t vs1053_SPI_ReadWriteByte( uint8_t TxData )
{
  /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

  /* Send byte through the SPI2 peripheral */
  SPI_I2S_SendData(SPI2, TxData);

  /* Wait to receive a byte */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2);
}

void vs1053_Init(void)
{		  
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);
  /* Configure SPI2 pins: SCK, MISO and MOSI ---------------------------------*/ 
  GPIO_InitStructure.GPIO_Pin = SCK_PIN  | MISO_PIN | MOSI_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SPI_PORT, &GPIO_InitStructure);

  /* XCS */
  GPIO_InitStructure.GPIO_Pin =  CCS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SPI_PORT, &GPIO_InitStructure);

  /* XDCS */
  GPIO_InitStructure.GPIO_Pin =  DCS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* DREQ */
  GPIO_InitStructure.GPIO_Pin = DREQ_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

  /* Reset */
  GPIO_InitStructure.GPIO_Pin = RES_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

  MP3_Reset(0);
  delay_ms(1);
  MP3_Reset(1);

  MP3_DCS(1); 
  MP3_CCS(1); 

  vs1053_SPI_Init();
}

void vs1053_WriteReg( uint8_t reg,uint16_t value )
{  
   while(  MP3_DREQ ==0 );
   
   vs1053_SPI_SetSpeed( SPI_SPEED_LOW );
   MP3_DCS(1); 
   MP3_CCS(0); 
   vs1053_SPI_ReadWriteByte(VS_WRITE_COMMAND);
   vs1053_SPI_ReadWriteByte(reg);
   vs1053_SPI_ReadWriteByte(value>>8);
   vs1053_SPI_ReadWriteByte(value);
   MP3_CCS(1);         
   vs1053_SPI_SetSpeed( SPI_SPEED_HIGH );
} 

uint16_t vs1053_ReadReg( uint8_t reg)
{ 
   uint16_t value;
    
   while(  MP3_DREQ ==0 );
   vs1053_SPI_SetSpeed( SPI_SPEED_LOW );
   MP3_DCS(1);     
   MP3_CCS(0);     
   vs1053_SPI_ReadWriteByte(VS_READ_COMMAND);
   vs1053_SPI_ReadWriteByte( reg );
   value = vs1053_SPI_ReadWriteByte(0xff);
   value = value << 8;
   value |= vs1053_SPI_ReadWriteByte(0xff);
   MP3_CCS(1);   
   vs1053_SPI_SetSpeed( SPI_SPEED_HIGH );
   return value; 
} 

void vs1053_ResetDecodeTime(void)
{
   vs1053_WriteReg(SPI_DECODE_TIME,0x0000);
   vs1053_WriteReg(SPI_DECODE_TIME,0x0000);
}

uint16_t vs1053_GetDecodeTime(void)
{ 
   return vs1053_ReadReg(SPI_DECODE_TIME);
} 


void vs1053_SoftReset(void)
{
   uint8_t retry; 	
   			   
   while(  MP3_DREQ ==0 );
   vs1053_SPI_ReadWriteByte(0xff);
   retry = 0;
   while( vs1053_ReadReg(SPI_MODE) != SM_SDINEW )
   {
	   vs1053_WriteReg(SPI_MODE,SM_SDINEW);
	   delay_ms(2);
	   if( retry++ > 100 )
	   { 
	      break; 
	   }
   }	 	

   while(  MP3_DREQ ==0 );

   retry = 0;

   while( vs1053_ReadReg(SPI_CLOCKF) != SC_MULT_XTALIx35 )
   {
	   vs1053_WriteReg(SPI_CLOCKF,SC_MULT_XTALIx35);
	   if( retry++ > 100 )
	   { 
	      break; 
	   }
   }		   
   retry = 0;

   MP3_DCS(0);
   vs1053_SPI_ReadWriteByte(0XFF);
   vs1053_SPI_ReadWriteByte(0XFF);
   vs1053_SPI_ReadWriteByte(0XFF);
   vs1053_SPI_ReadWriteByte(0XFF);
   MP3_DCS(1);
   delay_ms(20);
} 

void vs1053_Reset(void)
{
   delay_ms(20);
   vs1053_SPI_ReadWriteByte(0XFF);
   MP3_DCS(1);
   MP3_CCS(1);

   while(  MP3_DREQ ==0 );
   delay_ms(20);			 
}

void vs1053_SineTest(void)
{	

   while(  MP3_DREQ ==0 );  
 	
   MP3_DCS(0);
   vs1053_SPI_ReadWriteByte(0x53);
   vs1053_SPI_ReadWriteByte(0xef);
   vs1053_SPI_ReadWriteByte(0x6e);
   vs1053_SPI_ReadWriteByte(0x24);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   delay_ms(100);
   MP3_DCS(1); 
   
   MP3_DCS(0);
   vs1053_SPI_ReadWriteByte(0x45);
   vs1053_SPI_ReadWriteByte(0x78);
   vs1053_SPI_ReadWriteByte(0x69);
   vs1053_SPI_ReadWriteByte(0x74);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   delay_ms(100);
   MP3_DCS(1);

   MP3_DCS(0);
   vs1053_SPI_ReadWriteByte(0x53);
   vs1053_SPI_ReadWriteByte(0xef);
   vs1053_SPI_ReadWriteByte(0x6e);
   vs1053_SPI_ReadWriteByte(0x44);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   delay_ms(100);
   MP3_DCS(1);
   
   MP3_DCS(0);
   vs1053_SPI_ReadWriteByte(0x45);
   vs1053_SPI_ReadWriteByte(0x78);
   vs1053_SPI_ReadWriteByte(0x69);
   vs1053_SPI_ReadWriteByte(0x74);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   vs1053_SPI_ReadWriteByte(0x00);
   delay_ms(100);
   MP3_DCS(1);
}


void vs1053_SetVol(void)
{
   uint8_t i;
   uint16_t bass=0;
   uint16_t volt=0;
   uint8_t  vset=0;
		 
   vset = 255 - vs1053ram[4];
   volt =vset;
   volt <<= 8;
   volt += vset;
   /* 0,henh.1,hfreq.2,lenh.3,lfreq */      
   for( i = 0; i < 4; i++ )
   {
       bass <<= 4;
       bass += vs1053ram[i];
   }     
   vs1053_WriteReg(SPI_BASS,bass);
   vs1053_WriteReg(SPI_VOL,volt);
}    

void vs1053_WriteData( uint8_t * buf)
{		
   uint8_t  count = 32;

   MP3_DCS(0);   
   while( count-- )
   {
	  vs1053_SPI_ReadWriteByte( *buf++ );
   }
   MP3_DCS(1);  
   MP3_CCS(1);  
} 

void vs1053_Record_Init(void)
{
  uint8_t retry; 	

  /* Р•РґР¦Р“РљВ±Р¦РЈ */
  while( vs1053_ReadReg(SPI_CLOCKF) != 0x9800 )
  {
	  vs1053_WriteReg(SPI_CLOCKF,0x9800);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	

  while( vs1053_ReadReg(SPI_BASS) != 0x0000 )
  {
	  vs1053_WriteReg(SPI_CLOCKF,0x0000);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	

  /* Set sample rate divider=12 */ 
  while( vs1053_ReadReg(SPI_AICTRL0) != 0x0012 )
  {
	  vs1053_WriteReg(SPI_AICTRL0,0x0012);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	

  /* AutoGain OFF, reclevel 0x1000 */ 
  while( vs1053_ReadReg(SPI_AICTRL1) != 0x1000 )
  {
	  vs1053_WriteReg(SPI_AICTRL1,0x1000);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	

  /* RECORD,NEWMODE,RESET */ 
  while( vs1053_ReadReg(SPI_MODE) != 0x1804 )
  {
	  vs1053_WriteReg(SPI_MODE,0x1804);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	

  while( vs1053_ReadReg(SPI_CLOCKF) != 0x9800 )
  {
	  vs1053_WriteReg(SPI_CLOCKF,0x9800);
	  delay_ms(2);                        /* ВµР�Т‘СЌР¦Р‘Р™Р©1.35ms */
	  if( retry++ > 100 )
	  { 
	      break; 
	  }
  }	
}

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/

